package com.hippoDocker.security.filter;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.hippoDocker.security.pojo.dto.LoginUserDTO;
import com.hippoDocker.security.service.RedisService;
import com.hippoDocker.security.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * @ClassName JwtAuthenticationTokenfilter
 * @Description TODO Jwt认证过滤器(继承Spring继承servlet过滤器Filter的实现类)-不同版本的servlet情况不同，继承spring的过滤器就没问题
 * @Author tangxl
 * @Date 2022/7/27 14:21
 **/
@Component
public class JwtAuthenticationTokenfilter extends OncePerRequestFilter {
    @Autowired
    private RedisService redisService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取token
        String token = request.getHeader("token");
        //判断是否有token
        if(StrUtil.isBlank(token)){
            //请求头没有token放行
            filterChain.doFilter(request, response);
            return;
        }
        //解析token
        String userId = JwtUtil.parseJWT(token);
        if (userId == null) {
            //token不存在抛出异常
            throw new RuntimeException("token非法");
        }
        //从redis获取用户信息
        Object object = redisService.get("login:"+userId);
        if(Objects.isNull(object)){
            //redis缓存中用户信息不存在
            throw new RuntimeException("用户未登录");
        }
        LoginUserDTO loginUserDTO = Convert.convert(LoginUserDTO.class,object);
        //存入SecurityContextHolder
        //TODO UsernamePasswordAuthenticationToken第三个参数为权限信息
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginUserDTO, null,loginUserDTO.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        //验证通过放行
        filterChain.doFilter(request, response);
    }
}
